package VLine

import (
	"fmt"
)

type Function struct {
	parameters   []*Token
	instructions []*Instruction
	layer        *Layer
	upvalue      map[string]interface{}
	result       interface{}
	size         int
}

func FunctionNew(layer *Layer, parameters []*Token, instructions []*Instruction, size int) *Function {
	return &Function{
		parameters:   make([]*Token, 0),
		instructions: instructions,
		layer:        layer,
		upvalue:      make(map[string]interface{}),
		size:         size,
	}
}

func (function *Function) CallX(line *Line, this interface{}, args *Table) {
	var sLine = LineNew(line.constants, function.instructions, line.functions, function.size)
	sLine.Run()
	function.result = sLine.result
}

func (function *Function) Call(line *Line, this interface{}, args []interface{}) {
	var sLine = LineNew(line.constants, function.instructions, line.functions, function.size)
	sLine.register[0] = this
	for i := 0; i < len(args); i++ {
		sLine.register[i+1] = args[i]
	}
	sLine.upvalue = function.upvalue
	sLine.Run()
	function.result = sLine.result
}

func (function *Function) String() string {
	var str = "Function\n"
	for i := 0; i < len(function.instructions); i++ {
		str += fmt.Sprintln(function.instructions[i])
	}
	return str
}
